package pub.cleangao.mybatis.execution;

import pub.cleangao.mybatis.expression.BetweenExpression;
import pub.cleangao.mybatis.expression.ValueExpression;
import pub.cleangao.mybatis.expression.WhereExpression;
import pub.cleangao.mybatis.expression.WhereExpressionType;
import pub.cleangao.mybatis.spi.SpiContext;

import java.sql.SQLException;
import java.util.List;

public abstract class AbstractExecution implements Execution {

    /**
     * 交由任务处理器执行
     */
    public Object done() throws SQLException {
        return runInDataSource(SpiContext.getConnection0());
    }

    /**
     * 创建where查询条件
     * @param sql StringBuilder对象
     * @param whereExpressionList whereList
     */
    protected String generateWhereClause(StringBuilder sql, List<WhereExpression> whereExpressionList) {
        if (whereExpressionList == null || whereExpressionList.isEmpty()) {
            return sql.toString();
        }
        WhereExpression first = whereExpressionList.get(0);
        sql.append(generateWhereClause(first, true));
        for (int i = 1; i < whereExpressionList.size(); i++) {
            sql.append(generateWhereClause(whereExpressionList.get(i), false));
        }
        return sql.toString();
    }

    /**
     * 构建where条件
     *
     * @param expression where表达式
     * @param isFirst    是否是第一个
     */
    private String generateWhereClause(WhereExpression expression, boolean isFirst) {
        StringBuilder clause = new StringBuilder();
        if (expression.type().equals(WhereExpressionType.BETWEEN)) {
            BetweenExpression betweenExpression = (BetweenExpression) expression;
            if (!isFirst) {
                clause.append(betweenExpression.joint());
            }
            clause.append(" ");
            clause.append(betweenExpression.column());
            clause.append(" BETWEEN ");
            clause.append(betweenExpression.startValue());
            clause.append(" AND ");
            clause.append(betweenExpression.endValue());
        } else if (expression.type().equals(WhereExpressionType.VALUE)) {
            ValueExpression valueExpression = (ValueExpression) expression;
            if (!isFirst) {
                clause.append(valueExpression.joint());
            }
            clause.append(" ");
            clause.append(valueExpression.column());
            clause.append(valueExpression.operator().getOperator());
            clause.append(valueExpression.targetValue());
        }
        return clause.toString();
    }

}
